﻿using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels
{
    public class FxCopDictionaryViewModel : ViewModelBase
    {
        public EventHandler Saved;

        public EventHandler CloseRequired;


        private FxCopDictionary model;


        public ICollection<DictionaryTermViewModel> Recognized { get; private set; }

        public ICollection<DictionaryTermViewModel> Unrecognized { get; private set; }

        public ICollection<DictionaryTermViewModel> Deprecated { get; private set; }

        public ICollection<DictionaryTermViewModel> Compound { get; private set; }

        public ICollection<DictionaryTermViewModel> DiscreteExceptions { get; private set; }

        public ICollection<DictionaryTermViewModel> CasingExceptions { get; private set; }

        public RelayCommand SaveAndCloseCommand { get; private set; }

        public RelayCommand SaveCommand { get; private set; }

        public RelayCommand CloseCommand { get; private set; }


        public FxCopDictionaryViewModel(FxCopDictionary model)
        {
            this.model = model;
            Recognized = new ObservableCollection<DictionaryTermViewModel>();
            Unrecognized = new ObservableCollection<DictionaryTermViewModel>();
            Deprecated = new ObservableCollection<DictionaryTermViewModel>();
            Compound = new ObservableCollection<DictionaryTermViewModel>();
            DiscreteExceptions = new ObservableCollection<DictionaryTermViewModel>();
            CasingExceptions = new ObservableCollection<DictionaryTermViewModel>();
            SaveAndCloseCommand = new RelayCommand(o => { Save(); Close(); });
            SaveCommand = new RelayCommand(o => Save());
            CloseCommand = new RelayCommand(o => Close());

            if (model.Words != null)
            {
                model.Words.Recognized.Select(o => new DictionaryTermViewModel { Value = o }).ToList().ForEach(o => Recognized.Add(o));
                model.Words.Unrecognized.Select(o => new DictionaryTermViewModel { Value = o }).ToList().ForEach(o => Unrecognized.Add(o));
                model.Words.Deprecated.Select(o => new DictionaryTermViewModel { Value = o.Value, Alternate = o.Alternate }).ToList().ForEach(o => Deprecated.Add(o));
                model.Words.Compound.Select(o => new DictionaryTermViewModel { Value = o.Value, Alternate = o.Alternate }).ToList().ForEach(o => Compound.Add(o));
                model.Words.DiscreteExceptions.Select(o => new DictionaryTermViewModel { Value = o }).ToList().ForEach(o => DiscreteExceptions.Add(o));
            }
            if (model.Acronyms != null)
            {
                model.Acronyms.CasingExceptions.Select(o => new DictionaryTermViewModel { Value = o }).ToList().ForEach(o => CasingExceptions.Add(o));
            }
        }


        private void Save()
        {
            if (model.Words == null)
            {
                model.Words = new Words();
            }
            else
            {
                model.Words.Recognized.Clear();
                model.Words.Unrecognized.Clear();
                model.Words.Deprecated.Clear();
                model.Words.Compound.Clear();
                model.Words.DiscreteExceptions.Clear();
            }

            if (model.Acronyms == null)
            {
                model.Acronyms = new Acronyms();
            }
            else
            {
                model.Acronyms.CasingExceptions.Clear();
            }

            Recognized.Select(o => o.Value).ToList().ForEach(o => model.Words.Recognized.Add(o));
            Unrecognized.Select(o => o.Value).ToList().ForEach(o => model.Words.Unrecognized.Add(o));
            Deprecated.Select(o => new DeprecatedTerm { Value = o.Value, Alternate = o.Alternate }).ToList().ForEach(o => model.Words.Deprecated.Add(o));
            Compound.Select(o => new CompoundTerm { Value = o.Value, Alternate = o.Alternate }).ToList().ForEach(o => model.Words.Compound.Add(o));
            DiscreteExceptions.Select(o => o.Value).ToList().ForEach(o => model.Words.DiscreteExceptions.Add(o));
            CasingExceptions.Select(o => o.Value).ToList().ForEach(o => model.Acronyms.CasingExceptions.Add(o));

            model.Save();

            if (Saved != null)
            {
                Saved(this, EventArgs.Empty);
            }
        }

        private void Close()
        {
            if (CloseRequired != null)
            {
                CloseRequired(this, EventArgs.Empty);
            }
        }


        public class DictionaryTermViewModel : ViewModelBase
        {
            private string value;

            private string alternate;


            public string Value
            {
                get { return value; }
                set { this.value = value; OnPropertyChanged("Value"); }
            }

            public string Alternate
            {
                get { return alternate; }
                set { alternate = value; OnPropertyChanged("Alternate"); }
            }
        }
    }
}
